package first.endtoend;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.json.JSONException;
import org.json.JSONObject;
import org.mbds.wolf.http.HttpFormat;
import org.mbds.wolf.http.HttpRequest;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

import com.androidquery.AQuery;
import com.androidquery.callback.AjaxCallback;
import com.androidquery.callback.AjaxStatus;

import first.endtoend.adapters.ConfirmationAdapter;
import first.endtoend.facades.PortfolioDetailFacade;
import first.endtoend.facades.TraceDetailFacade;
import first.endtoend.facades.TraceFacade;
import first.endtoend.helpers.Constant;
import first.endtoend.helpers.DialogHelper;
import first.endtoend.helpers.InternetHelper;
import first.endtoend.helpers.JsonHelper;
import first.endtoend.models.PortfolioDetail;
import first.endtoend.models.Product;
import first.endtoend.models.Trace;
import first.endtoend.models.TraceDetail;


public class ConfirmationSupplyActivity extends MyActivity  {

	ImageView img;
	String imageFilePath;
	static File imageFile;
	String photo;
	Trace trace;
	TraceFacade trFacade;
	PortfolioDetail pf;
	TraceDetailFacade traceDetailFacade;
	PortfolioDetailFacade pfdFacade;
	AQuery aquery;

	float accuracy;
	double longitude, latitude;
	
	Product product;
	float quantity;

	ConfirmationAdapter adapter;
	List<PortfolioDetail> productsSeleted;
	Button completeBtn;
	private LocationManager lm;
	@SuppressWarnings("unused")
	private Location location;
	public ProgressDialog progressDialog;
	AlertDialog.Builder alert;
	
	
	String FILETOKEN = "token";
	String tokenStr;

	String responseStr;
	int responsecode;
	ProgressDialog pDialog;
	
	final static LoginActivity log_act= new LoginActivity();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_confirmation);
		progressDialog = new ProgressDialog(this);
		aquery = new AQuery(this);

		try {
			trFacade = new TraceFacade(this);
			traceDetailFacade = new TraceDetailFacade(this);
			pfdFacade = new PortfolioDetailFacade(this);
		} catch (Exception e) {
			e.printStackTrace();
		}

		this.takePhoto();

		productsSeleted = ListBeneficiariesActivity.portfolio.getProductsSelected();

		adapter = new ConfirmationAdapter(ConfirmationSupplyActivity.this, productsSeleted);
		ListView listeview = (ListView) findViewById(R.id.listViewConfirm);
		listeview.setAdapter(adapter);

		completeBtn = (Button) findViewById(R.id.validBtnConfirm);
		completeBtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				trace = new Trace(TagActivity.family.getBeneficiarySelected(), latitude, longitude, accuracy, new Date(System.currentTimeMillis()), photo, LoginActivity.user.getId());
				
				GPSTracker gps = new GPSTracker(ConfirmationSupplyActivity.this);
				//Check if the GPS is enabled or no 
				if(gps.canGetLocation()){
					latitude = gps.getLatitude();
					longitude= gps.getLongitude();
                    Toast.makeText(getApplicationContext(), "Your Location is - \nLatitude: " + latitude + "\nLongitude: " + longitude, Toast.LENGTH_LONG).show();    
				}else{
					//can't get location
                    // GPS or Network is not enabled
                    // Ask user to enable GPS/network in setting
					gps.showSettingsAlert();
				}
				
				if(trace.getPhoto() != null){
					
					if((trace.getLatitude() == 0) || (trace.getLongitude() ==0)){
						alert = new AlertDialog.Builder(ConfirmationSupplyActivity.this);
						DialogHelper.showGPSSettingsDialog(ConfirmationSupplyActivity.this, alert, getString(R.string.location_failed_message1));
					}
					else{
						try {
							processSupply();
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						catch (UnsupportedEncodingException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					
				}
				else{
					alert = new AlertDialog.Builder(ConfirmationSupplyActivity.this);
					DialogHelper.showErrorDialog(alert, getString(R.string.warning), 
							getString(R.string.no_photo_message));
				}
			}
		});

	}

	@Override
	protected void onResume() {
		super.onResume();
//		lm = (LocationManager) this.getSystemService(LOCATION_SERVICE);
//		if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){
//			System.out.println(">>>>>>>>>>> Location Manager used for position : GPS Provider");
//			lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,this);
//			
//		}else{
//			System.out.println(">>>>>>>>>>> Location Manager used for position : Network Provider");
//			lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,this);
//		}
	
		
	}
	
	//instance of the class GPS tracker 
	GPSTracker gps_tracker = new GPSTracker(this);  
	
	@Override
	protected void onPause() {
		super.onPause();
		gps_tracker.stopUsingGPS();
	}

	//decodes image and scales it to reduce memory consumption
	public Bitmap decodeFile(File f){
		try {
			//Decode image size
			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inJustDecodeBounds = true;
			BitmapFactory.decodeStream(new FileInputStream(f),null,o);

			//The new size we want to scale to
			final int REQUIRED_SIZE=70;

			//Find the correct scale value. It should be the power of 2.
			int width_tmp=o.outWidth, height_tmp=o.outHeight;
			int scale=1;
			while(true){
				if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
					break;
				width_tmp/=2;
				height_tmp/=2;
				scale*=2;
			}

			//Decode with inSampleSize
			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize=scale;
			return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
		} catch (FileNotFoundException e) {}
		return null;
	}


	public void takePhoto() {
	
		File file = new File(Environment.getExternalStorageDirectory(), getString(R.string.tracePhotosOffLine));

		if(file.mkdirs() || file.isDirectory()){
			imageFilePath = file.getAbsolutePath()+"/"+TagActivity.family.getFamilyName()+
					"_"+Trace.class.getSimpleName()+System.currentTimeMillis()+".jpg";
		}
		else{
			imageFilePath = file.getAbsolutePath()+"/"+TagActivity.family.getFamilyName()+
					"_"+Trace.class.getSimpleName()+System.currentTimeMillis()+".jpg";
		}

		img = (ImageView) findViewById(R.id.photo);
		img.setOnClickListener(new View.OnClickListener() {


			@Override
			public void onClick(View v) {
				imageFile = new File(imageFilePath);
				System.out.println(imageFile.toString());
				Uri imageFileUri = Uri.fromFile(imageFile);
				System.out.println(imageFileUri);
				Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
				intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
				System.out.println("The image file URI in the mobile is: "+imageFileUri);
				startActivityForResult(intent, 0);

			}
		});
	}


	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
		case 0:

			if (resultCode == RESULT_OK) {
				Bitmap bmp = decodeFile(imageFile);
				Bitmap bmpcomp = Bitmap.createScaledBitmap(bmp, 150, 150, true);

				// create a matrix object
				Matrix matrix = new Matrix();
				matrix.postRotate(90); // rotate of 0 degree in clock wise

				// create a new bitmap from the original using the matrix to transform the result
				Bitmap rotatedBitmap = Bitmap.createBitmap(bmpcomp, 0, 0,
						bmpcomp.getWidth(), bmpcomp.getHeight(), matrix, true);
				img.setImageBitmap(rotatedBitmap);

				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
				byte[] b = baos.toByteArray();
				photo = Base64.encodeToString(b, Base64.DEFAULT);

			}
			break;
		}

	}
	


	@Override
	public void onBackPressed() {
		super.onBackPressed();
		Intent intent = new Intent(ConfirmationSupplyActivity.this, SupplyActivity.class);
		startActivity(intent);
		finish();
	}

//	@Override
//	public void onLocationChanged(Location location) {
//		this.location = location;
//		lm.removeUpdates(this);
//		latitude = location.getLatitude();
//		longitude = location.getLongitude();
//		accuracy = location.getAccuracy();
//		String loc= "last known location is \n latitude= "+latitude+"\n longitude="+longitude+"\n and accuracy: "+accuracy;
//		System.out.println(loc);
//		Toast.makeText(this, "location is \n latitude= "+latitude+"\n longitude="+longitude+"\n", Toast.LENGTH_SHORT).show();
//	}
//
//
//	@Override
//	public void onProviderDisabled(String provider) {
//		Toast.makeText(getApplicationContext(), "GPS Disabled", Toast.LENGTH_SHORT).show();
//	}
//
//
//	@Override
//	public void onProviderEnabled(String provider) {
//		Toast.makeText(getApplicationContext(), "GPS enabled", Toast.LENGTH_SHORT).show();
//	}
//
//
//	@Override
//	public void onStatusChanged(String provider, int status, Bundle extras) {}


	public void processSupply() throws JSONException, UnsupportedEncodingException{
		if(InternetHelper.isOnline(ConfirmationSupplyActivity.this)){
			processSupplyOnline();
		}
		else{
			processSupplyOffline();
		}
	}

	/**
	 * Update data locally in case there is no internet connection
	 * */
	public void processSupplyOffline(){
 
		AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {

			@Override
			protected void onPreExecute() {
				DialogHelper.showProcessingDialog(progressDialog, getString(R.string.sending),
						getString(R.string.wait));	
			}

			@Override
			protected Void doInBackground(Void... arg0) {
				//System.out.println("No internet connection, updating local data on the mobile only");

				try {
					trFacade.insert(trace);
					for(PortfolioDetail pf : productsSeleted){
						TraceDetail detail = new TraceDetail(trace, pf.getProduct(), pf.getQuantityWished());
						
						trace.setLongitude(gps_tracker.longitude);
						trace.setLatitude(gps_tracker.latitude);
						
						System.out.println("the trace id is = "+trace.getTraceId());
						System.out.println("trace longitude is = "+trace.getLongitude());
						System.out.println("trace latitude is = "+trace.getLatitude());
						

						trace.getTraceDetails().add(detail);

						traceDetailFacade.insert(detail);

						pf.setQuantity(pf.getQuantity() - pf.getQuantityWished());

						pfdFacade.update(pf);
					}

				} catch (Exception e) {
					e.printStackTrace();
				}		
				return null;
			}

			@Override
			protected void onPostExecute(Void result) {
				progressDialog.dismiss();
				processSupplyFinishDialog();
			}

		};
		task.execute((Void[])null);

	}


/**
 * implementation of the SyncTrace WS to synchronize Data between mobile and backend after a transaction 
 * */ 	
	public void processSupplyOnline() {

		System.out.println("Connected to internet, SO data will be send to server");
		
		for (PortfolioDetail pf : productsSeleted) {
			TraceDetail detail = new TraceDetail(trace, pf.getProduct(),pf.getQuantityWished());
			System.out.println("location coordinates are longitude: "+trace.getLongitude()+"\n latitude: "+trace.getLatitude());
			trace.getTraceDetails().add(detail);

		}

		final JSONObject ob = JsonHelper.createJsonObject(trace);
		//System.out.println("JSON obj is= "+ ob);
		
		SharedPreferences settings = getSharedPreferences(log_act.PREF_NAME, 0); // load the preferences
		int port = Integer.parseInt(settings.getString("portNumb", "8080"));
		String res = HttpRequest.getInstance().query(settings.getString("url",null),port,HttpRequest.Method.POST,
						HttpFormat.APPLICATION_JSON,settings.getString("module", null)+ "/"+ getString(R.string.syncTrace)
								+ "/", null,ob.toString());
		String url = (settings.getString("url",null)+":"+port+"/"+settings.getString("module", null)+ "/"+ getString(R.string.syncTrace)+ "/");

		if (res != null)
			System.out.print("The server responds \n");
			
		DialogHelper.showProcessingDialog(progressDialog,getString(R.string.uploading), getString(R.string.wait));
		Map<String, Object> params = new HashMap<String, Object>();
		params.put(Constant.TRACE_KEY, ob.toString());
		
		System.out.println("les params sont = "+params);
		
		//String url = log_act.getServerUrl()+getString(R.string.syncTrace);
		aquery.progress(progressDialog).ajax(url, params, JSONObject.class, new AjaxCallback<JSONObject>() {
					@Override
					public void callback(String url, JSONObject json,AjaxStatus status) {
						switch (status.getCode()) {
						case Constant.REQUEST_OK:

							int code = JsonHelper.getResponseCodeFromJson(json.toString());
							System.out.println("the response code is="+code);

							switch (code) {
							case Constant.REQUEST_OK:
								System.out.println("communication with server success");
								processSupplyFinishDialog();
								for (PortfolioDetail pf : productsSeleted) {
									pf.setQuantity(pf.getQuantity()- pf.getQuantityWished());
									try {
										pfdFacade.update(pf);
									} catch (Exception e1) {
										// TODO Auto-generated catch block
										e1.printStackTrace();
									}
									
								}
								System.out.println("Trace "+ trace.getTraceId()+"is Sync in application Confirmation's Activity :");
								break;
							default:
								processSupplyOffline();
								System.out.println("call the supplyOffline");
								//System.out.println("No Internet Connection: Trace cannot be Sync right now in App Confirmation, Stored in local");
								break;
							}
							break;
						default:
							processSupplyOffline();
							Log.i("First Confirmation Activity "," updating transaction's data of Trace: "+ trace.getTraceId()+ " in local DB !!!");
							break;
						}

						try {
						} catch (Exception e) {
							e.printStackTrace();
						}
			//System.out.println("Data Value: " + ob.toString());
						
					}
				});
	}
	
	
	public void processSupplyFinishDialog() {
		alert = new AlertDialog.Builder(ConfirmationSupplyActivity.this);
		alert.setTitle(R.string.SuccessTransaction);
		alert.setMessage(R.string.SuccessTransactionMessage);
		alert.setIcon(R.drawable.successicon);
		alert.setCancelable(false);
		alert.setPositiveButton(R.string.start, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				Intent intent = new Intent(ConfirmationSupplyActivity.this, TagActivity.class);
				startActivity(intent);
				finish();
			}
		});
		alert.setNegativeButton(R.string.quit, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				DialogHelper.processingDisconnection(progressDialog, ConfirmationSupplyActivity.this);
			}
		});
		alert.show();

	}
}

	
